package com.lsa.helpers.tree;

import com.lsa.helpers.Pair;

public class RandomTreeFactory
{
    private static int idSeed;
    private static boolean isLog = false;
    
    public static ITree<Pair<String, Object>> createRandomTree(int count, boolean isBinary){
        idSeed = 1;
        TreeNode<Pair<String, Object>> root = createNode(count);
        int depth = 1;
        createSubtreeTree(depth, count - 1, root, isBinary);
        return new Tree<Pair<String, Object>>(root);
    }

    private static TreeNode<Pair<String, Object>> createNode(int count)
    {
        return new TreeNode<Pair<String, Object>>(new Pair<String, Object>(""+(idSeed++), ""+(idSeed -1)+":"+count));
    }
    
    public static void createSubtreeTree(int depth, int count, TreeNode<Pair<String, Object>> root){
        createSubtreeTree(depth, count, root, false);
    }
    
    public static void createSubtreeTree(int depth, int count, TreeNode<Pair<String, Object>> root, boolean isBinary){
    	TreeNode<Pair<String, Object>> child = createNode(count);
        root.addChild(child);
        --count;
        while(count > 0){
            int subtreeSize = random(1, count);
            for( int i = 0; i < depth - 1; i++ )
            {
                if (isLog) System.out.print(" ");
            }
            if (isLog) System.out.print(String.format("[%s = [%s %s]]{", subtreeSize, 1, count));
            if (isLog) System.out.println();
            createSubtreeTree(depth + 1,subtreeSize, child, isBinary);
            if (isBinary){
                if (count > subtreeSize){
                    createSubtreeTree(depth + 1, count - subtreeSize, child, isBinary);
                }
                count = 0;
            }
            else{
                count -= subtreeSize;
            }
            for( int i = 0; i < depth - 1; i++ )
            {
                if (isLog) System.out.print(" ");
            }
            if (isLog) System.out.print("}");
            if (isLog) System.out.println();
        }
    }
    
    private static int random(int lower, int upper){
        return (int)((double)(upper - lower + 1) * Math.random()) + lower;
    }
}
